package org.nimi317.web_gis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.nimi317.web_gis.dao.AreaMapper;
import org.nimi317.web_gis.dao.AreaQualityMapper;
import org.nimi317.web_gis.dao.ProvinceMapper;
import org.nimi317.web_gis.dao.StationMapper;
import org.nimi317.web_gis.entity.Area;
import org.nimi317.web_gis.entity.Province;
import org.nimi317.web_gis.entity.ProvinceQuality;
import org.nimi317.web_gis.form.post.ProvinceRenderPost;
import org.nimi317.web_gis.service.IUpdateService;
import org.nimi317.web_gis.service.ProvinceQualityService;
import org.nimi317.web_gis.service.ProvinceService;
import org.nimi317.web_gis.utils.TimeUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author thunderobot
 */
@Service
@AllArgsConstructor
@Transactional
public class ProvinceServiceImpl extends ServiceImpl<ProvinceMapper, Province> implements ProvinceService {

    private final ProvinceMapper provinceMapper;

    private final AreaMapper areaMapper;

    private final StationMapper stationMapper;

    private final AreaQualityMapper areaQualityMapper;

    private final IUpdateService updateService;

    private final ProvinceQualityService provinceQualityService;

    private final List<String> stringList = List.of("aqi", "pm25", "pm10", "so2", "no2", "co", "o3");

    @Override
    public List<ProvinceQuality> getHistory(ProvinceRenderPost post) {
        LocalDateTime time = TimeUtils.getDivisionDateTime(post.getType());
        LambdaQueryWrapper<ProvinceQuality> wrapper = new LambdaQueryWrapper<>();
        wrapper
                .eq(ProvinceQuality::getId, post.getId()).ge(ProvinceQuality::getTimestamp, time);
        return provinceQualityService.list(wrapper);
    }

    @Override
    public IPage<ProvinceQuality> getHistory(Integer id, List<LocalDateTime> range) {
        LambdaQueryWrapper<ProvinceQuality> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProvinceQuality::getId, id)
                .ge(ProvinceQuality::getTimestamp, range.get(0))
                .le(ProvinceQuality::getTimestamp, range.get(1));
        return provinceQualityService.page(null, wrapper);
    }

    @Override
    public List<ProvinceQuality> getHistoryList(Integer id, List<LocalDateTime> range) {
        LambdaQueryWrapper<ProvinceQuality> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProvinceQuality::getId, id)
                .ge(ProvinceQuality::getTimestamp, range.get(0))
                .le(ProvinceQuality::getTimestamp, range.get(1));
        return provinceQualityService.list(wrapper);
    }

    @Override
    public List<Object> getAreaCodes(Integer id) {
        LambdaQueryWrapper<Area> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Area::getCityCode)
                .eq(Area::getProvinceId, id);
        return areaMapper.selectMaps(queryWrapper).stream().map(s -> s.get("city_code")).toList();
    }

    @Override
    public List<ProvinceQuality> getRecurrent(Integer id) {
        LocalDateTime dateTime = TimeUtils.getCurrentUsefulDateTime();
        LambdaQueryWrapper<ProvinceQuality> wrapper = new LambdaQueryWrapper<>();
        wrapper.le(ProvinceQuality::getTimestamp, dateTime)
                .eq(ProvinceQuality::getId, id)
                .orderByDesc(ProvinceQuality::getTimestamp)
                .last("limit 24");
        return provinceQualityService.list(wrapper);
    }

    @Override
    public List<ProvinceQuality> getRealTime() {
        LocalDateTime time = updateService.getLastUpdateTime();
        LambdaQueryWrapper<ProvinceQuality> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProvinceQuality::getTimestamp, time);
        return provinceQualityService.list(wrapper);
    }
}
